<template>
  <el-row>
    <el-col :span="22">
      <div style="border: 1px solid #ccc; margin-top: 10px">
        <Toolbar
          :editor="editorRef"
          :defaultConfig="toolbarConfig"
          :mode="mode"
          style="border-bottom: 1px solid #ccc"
        />
        <Editor
          :defaultConfig="editorConfig"
          :mode="mode"
          v-model="valueHtml"
          :style="{ height: style.height, overflowY: 'hidden' }"
          @onCreated="handleCreated"
          @onDestroyed="handleDestroyed"
          @onFocus="handleFocus"
          @onBlur="handleBlur"
          @customPaste="customPaste"
        />
      </div>
    </el-col>
    <el-col :span="2">
      <slot name="right">
        <div class="wang-editor-right-btn-box">
          <el-button
            v-for="(tab, index) in rightTabs"
            :key="index"
            @click="insertHtml('{{ ' + tab + ' }}')"
          >
            {{ `插入${tab}` }}
          </el-button>
        </div>
      </slot>
    </el-col>
  </el-row>
  <Upload
    v-if="isUpload"
    :config="{ total: 9, file_type: file_type }"
    @returnImgs="returnImgsFunc"
    >上传图片</Upload
  >
</template>

<script setup lang="ts">
import "@wangeditor/editor/dist/css/style.css";
import { onBeforeUnmount, ref, shallowRef, onMounted, computed } from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { IEditorConfig, IToolbarConfig } from "@wangeditor/editor";
import Upload from "@/components/file/Upload.vue";
const props = defineProps({
  text: {
    type: String,
    default: "",
  },
  config: {
    type: Object,
    default: () => {
      return {};
    },
  },
  insertTabs: {
    type: Array,
    default: () => {
      return [] as string[];
    },
  },
});
const emits = defineEmits(["update:text"]);
const isUpload = ref(false);
const file_type = ref("image");
// 编辑器实例，必须用 shallowRef，重要！
const editorRef = shallowRef();
const mode = ref("default");
// 内容 HTML
const valueHtml = computed({
  get() {
    return props.text;
  },
  set(val) {
    emits("update:text", val);
  },
});
const rightTabs = computed(() => {
  return props.insertTabs;
});
const style = computed(() => {
  return {
    ...props.config,
    height: "500px",
  };
});
const toolbarConfig: Partial<IToolbarConfig> = {
  excludeKeys: ["insertImage", "insertVideo"], // 不显示网络图片和网络视频选项
};
type InsertFnType = (url: string, alt: string, href: string) => void;
let returnImgsFunc: ((imgs: string[]) => void) | null = null;
const editorConfig: Partial<IEditorConfig> = {
  placeholder: "请输入内容",
  // TS 语法
  // const editorConfig = {                       // JS 语法
  MENU_CONF: {
    uploadImage: {
      customBrowseAndUpload: (insertFn: InsertFnType) => {
        file_type.value = "image";
        isUpload.value = true;
        returnImgsFunc = (imgs: any[]) => {
          imgs.forEach((item) => {
            insertFn(item.file_path, "", "");
          });
          isUpload.value = false;
        };
      },
    },
    uploadVideo: {
      customBrowseAndUpload: (insertFn: InsertFnType) => {
        file_type.value = "video";
        isUpload.value = true;
        returnImgsFunc = (imgs: any[]) => {
          imgs.forEach((item) => {
            insertFn(item.file_path, "", "");
          });
          isUpload.value = false;
        };
      },
    },
  },
  // 其他属性...
};

// 组件销毁时，也及时销毁编辑器，重要！
onBeforeUnmount(() => {
  const editor = editorRef.value;
  if (editor == null) return;

  editor.destroy();
});

// 编辑器回调函数
const handleCreated = (editor: any) => {
  console.log(); // 当前菜单排序和分组
  editorRef.value = editor; // 记录 editor 实例，重要！
};

const handleDestroyed = (editor: any) => {
  console.log("destroyed", editor);
};

const handleFocus = (editor: any) => {
  console.log("focus", editor);
};

const handleBlur = (editor: any) => {
  console.log("blur", editor);
};

const customPaste = (editor: any, event: any, callback: any) => {
  console.log("ClipboardEvent 粘贴事件对象", event);
  //获取粘贴的文本
  const clipboardData = event.clipboardData;
  console.log("ClipboardData 粘贴板对象", clipboardData);
  if (clipboardData == null) {
    // 粘贴的是其他内容
    console.log("粘贴的是其他内容");
    return;
  }
  if (clipboardData.types.includes("text/html")) {
    // 粘贴的是富文本
    console.log("粘贴的是富文本");
    return;
  }
  if (clipboardData.types.includes("Files")) {
    // 粘贴的是图片
    console.log("粘贴的是图片");
    return;
  }
  // 返回值（注意，vue 事件的返回值，不能用 return）
  callback(false); // 返回 false ，阻止默认粘贴行为
  // callback(true) // 返回 true ，继续默认的粘贴行为
};

const insertHtml = (content: string) => {
  const editor = editorRef.value;
  editor.insertText(content);
};

defineExpose({
  insertHtml,
});
</script>
<style lang="scss" scoped>
.wang-editor-right-btn-box {
  display: flex;
  flex-direction: column;
  .el-button {
    margin-left: 12px;
    margin-top: 10px;
  }
}
</style>
